home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- subscribe.c
-
- This module handles subscribing and unsubscribing to groups.
-
- Copyright © 1994-1995, Northwestern University.
-
- ----------------------------------------------------------------------------*/
-
- #include <string.h>
- #include <stdio.h>
-
- #include "glob.h"
- #include "dialog.h"
- #include "child.h"
- #include "newswatcher.h"
- #include "subscribe.h"
- #include "news.h"
- #include "memutil.h"
- #include "windutil.h"
- #include "listutil.h"
- #include "strutil.h"
- #include "group.h"
- #include "full.h"
-
-
-
- #define kDuplicateGroupsAlert 151
-
-
-
- /*----------------------------------------------------------------------------
- PresentDuplicateGroupsAlert
-
- Present the duplicate groups alert.
-
- Entry: numDuplicates = number of duplicate groups.
- dupNameOffset = offset in gGroupNames of duplicate group
- name if numDuplicates = 1.
- drag = true if drag and drop, false if paste.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr PresentDuplicateGroupsAlert (short numDuplicates,
- long dupNameOffset, Boolean drag)
- {
- CStr255 msg, fmt, groupName, movingOrPasting;
- DialogPtr dlg;
- short len, groupNameLen, item;
- OSErr err = noErr;
-
- GetCString(drag ? kStrMoving : kStrPasting, movingOrPasting);
-
- if (numDuplicates > 1) {
- GetCString(kStrDuplicateGroups, fmt);
- sprintf(msg, fmt, movingOrPasting, movingOrPasting);
- } else {
- GetCString(kStrOneDuplicateGroup, fmt);
- strcpy(groupName, *gGroupNames + dupNameOffset);
- groupNameLen = strlen(groupName);
- len = strlen(fmt) + groupNameLen + strlen(movingOrPasting) - 4;
- if (len > 255) {
- groupNameLen -= len - 255;
- groupName[groupNameLen-3] = '.';
- groupName[groupNameLen-2] = '.';
- groupName[groupNameLen-1] = '.';
- groupName[groupNameLen] = 0;
- }
- sprintf(msg, fmt, groupName, movingOrPasting);
- }
- c2pstr(msg);
-
- err = MyGetNewDialog(kDuplicateGroupsAlert, ok, cancel, &dlg);
- if (err != noErr) return err;
- ParamText((StringPtr)msg, "\p", "\p", "\p");
- SysBeep(0);
- MyModalDialog(dlg, gDialogFilterUPP, &item);
- err = DoClose(dlg);
- if (err != noErr) return err;
- if (item == cancel) return userCanceledErr;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ClearStatus
-
- Clear the status fields in all groups in a window.
-
- Entry: wind = pointer to group list window.
- ----------------------------------------------------------------------------*/
-
- static void ClearStatus (WindowPtr wind)
- {
- TWindow **info;
- ListHandle theList;
- TGroup **groupArray;
- Cell theCell;
- short cellDataLen, index, numGroups;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- groupArray = (**info).groupArray;
- numGroups = (**theList).dataBounds.bottom;
- theCell.h = 0;
- for (theCell.v = 0; theCell.v < numGroups; theCell.v++) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- (*groupArray)[index].status = ' ';
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- GroupInList
-
- Check to see if a named group appears in a group list window, and
- set the status field to 'x' if the group does appear.
-
- Entry: nameOffset = offset in gGroupNames of group name.
- wind = pointer to group list window.
-
- Exit: function result = true if group in window.
- ----------------------------------------------------------------------------*/
-
- static Boolean GroupInList (long nameOffset, WindowPtr wind)
- {
- TWindow **info;
- ListHandle theList;
- TGroup **groupArray;
- Cell theCell;
- short numGroups, cellDataLen, index;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- groupArray = (**info).groupArray;
- numGroups = (**theList).dataBounds.bottom;
- theCell.h = 0;
- for (theCell.v = 0; theCell.v < numGroups; theCell.v++) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- if ((*groupArray)[index].nameOffset == nameOffset) {
- (*groupArray)[index].status = 'x';
- return true;
- }
- }
- return false;
- }
-
-
-
- /*----------------------------------------------------------------------------
- RemoveDuplicates
-
- Remove duplicate groups (the ones marked with status 'x').
-
- Entry: wind = pointer to user group list window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr RemoveDuplicates (WindowPtr wind)
- {
- WindowPtr child;
- TWindow **info;
- ListHandle theList;
- TGroup **groupArray, groupInfo;
- Cell theCell;
- short numDel = 0;
- GrafPtr port;
- OSErr err = noErr;
- short cellDataLen, index, numGroups;
-
- GetPort(&port);
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- groupArray = (**info).groupArray;
- numGroups = (**theList).dataBounds.bottom;
-
- LSetDrawingMode(false, theList);
- theCell.h = 0;
- for (theCell.v = 0; theCell.v < numGroups; theCell.v++) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- groupInfo = (*groupArray)[index];
- if (groupInfo.status == 'x') {
- if ((child = FindChild(wind, theCell)) != nil) {
- err = DoClose(child);
- if (err != noErr) goto exit;
- }
- DisposeGroupUnreadList(&groupInfo);
- (*groupArray)[index] = groupInfo;
- LDelRow(1, theCell.v, theList);
- numDel++;
- theCell.v--;
- numGroups--;
- }
- }
- LSetDrawingMode(true, theList);
- SetPort(port);
- return noErr;
-
- exit:
-
- SetPort(port);
- return err;
- }
-
-
-
-
- /*----------------------------------------------------------------------------
- RedrawGroupCount
-
- Redraw the count in the panel area of a group window.
-
- Entry: wind = pointer to group window.
- ----------------------------------------------------------------------------*/
-
- static void RedrawGroupCount (WindowPtr wind)
- {
- GrafPtr port;
- TWindow **info;
- Rect r;
-
- GetPort(&port);
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
- r = wind->portRect;
- r.bottom = (**info).panelHeight-3;
- InvalRect(&r);
- SetPort(port);
- }
-
-
-
- /*----------------------------------------------------------------------------
- RemoveGroupFromUnsubscribedList
-
- Remove a group from the unsubscribed list.
-
- Entry: groupName = group name.
- unsubscribed = handle to unsubscribed list.
- ----------------------------------------------------------------------------*/
-
- void RemoveGroupFromUnsubscribedList (char *groupName, Handle unsubscribed)
- {
- long len, unsubscribedLen;
- char *p, *pEnd, *q;
-
- if (unsubscribed == nil) return;
- len = strlen(groupName);
- unsubscribedLen = MyGetHandleSize(unsubscribed);
- p = *unsubscribed;
- pEnd = p + unsubscribedLen;
- while (p < pEnd) {
- q = p;
- while (q < pEnd && *q != CR) q++;
- q++;
- if (MyStrNEqual(p, groupName, len)) break;
- p = q;
- }
- if (p > pEnd) return;
- len = q-p;
- BlockMoveData(q, p, pEnd-q);
- MySetHandleSize(unsubscribed, unsubscribedLen - len);
- }
-
-
-
- /*----------------------------------------------------------------------------
- AddNewGroup
-
- Add a new group to a user group window.
-
- Entry: nameOffset = offset in gGroupNames of group name to add.
- wind = pointer to user group window.
- pos = position of new user group list entry (row number
- of new cell). Pass 0x7fff to add at end of list.
- theGroup = pointer to group info to add, or nil to get info
- for new group from server.
- cloneUnreadList = true to clone a copy of the unread list
- in theGroup.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr AddNewGroup (long nameOffset, WindowPtr wind, short pos,
- TGroup *theGroup, Boolean cloneUnreadList)
- {
- ListHandle theList;
- Cell theCell;
- TWindow **info;
- TGroup **groupArray, newGroup;
- short newGroupIndex;
- OSErr err = noErr;
- Boolean groupExists;
- GrafPtr port;
- TUnread **unread, **newUnread, **prevNewUnread;
- CStr255 groupName;
-
- GetPort(&port);
-
- newGroup.firstMess = 1;
- newGroup.lastMess = 0;
- newGroup.numUnread = 0;
- newGroup.unread = nil;
- newGroup.status = ' ';
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- groupArray = (**info).groupArray;
- strcpy(groupName, *gGroupNames + nameOffset);
-
- if (theGroup == nil) {
- newGroup.nameOffset = nameOffset;
- newGroup.onlyRedrawCount = false;
- err = GetGroupArticleRange(&newGroup, &groupExists);
- if (err != noErr) goto exit;
- if (groupExists && newGroup.firstMess <= newGroup.lastMess) {
- err = MyNewHandle(sizeof(TUnread), &unread);
- if (err != noErr) goto exit;
- (**unread).firstUnread = newGroup.firstMess;
- (**unread).lastUnread = newGroup.lastMess;
- (**unread).next = nil;
- newGroup.unread = unread;
- }
- } else {
- newGroup = *theGroup;
- if (cloneUnreadList) {
- newGroup.unread = nil;
- unread = theGroup->unread;
- prevNewUnread = nil;
- while (unread != nil) {
- err = MyNewHandle(sizeof(TUnread), &newUnread);
- if (err != noErr) goto exit;
- **newUnread = **unread;
- (**newUnread).next = nil;
- if (prevNewUnread == nil) {
- newGroup.unread = newUnread;
- } else {
- (**prevNewUnread).next = newUnread;
- }
- prevNewUnread = newUnread;
- unread = (**unread).next;
- }
- }
- }
-
- err = MySetHandleSize(groupArray, MyGetHandleSize(groupArray) + sizeof(TGroup));
- if (err != noErr) goto exit;
- newGroupIndex = (**info).numGroups;
- (**info).numGroups++;
- (*groupArray)[newGroupIndex] = newGroup;
-
- LSetDrawingMode(false, theList);
- pos = LAddRow(1, pos, theList);
- SetPt(&theCell, 0, pos);
- LSetCell(&newGroupIndex, 2, theCell, theList);
- LSetDrawingMode(true, theList);
-
- RemoveGroupFromUnsubscribedList(groupName, (**info).unsubscribed);
-
- SetPort(wind);
- InvalRect(&wind->portRect);
-
- (**info).changed = true;
- SetPort(port);
- return noErr;
-
- exit:
-
- SetPort(port);
- DisposeGroupUnreadList(&newGroup);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- CopyGroupsFromScrap
-
- Copy groups from scrap data to a user group list window.
-
- Entry: data = handle to scrap data. WARNING: The scrap data is
- modified by this function.
- wind = pointer to destination user group list window.
- pos = position of new user group list entries in destination
- window (starting row number of new cells).
- Pass 0x7fff to add at end of list.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr CopyGroupsFromScrap (Handle data, WindowPtr wind, short pos)
- {
- TWindow **info;
- ListHandle theList;
- long dataPos, groupNameLen, nameOffset, numUnreadPairs;
- long numGroups, i, dupNameOffset;
- short firstPos;
- CStr255 groupName;
- TGroup theGroup;
- TUnread **prevUnread, **unread;
- OSErr err = noErr;
- short numSubscribed, index, numCells;
- short numDuplicates, numNotInFullGroupList;
- Cell theCell;
- GrafPtr port;
- Rect r;
- long j, jDataPos, jGroupNameLen;
-
- GetPort(&port);
- SetPort(wind);
-
- theGroup.unread = nil;
-
- err = CheckScrapData(data);
- if (err != noErr) goto exit;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- numCells = (**theList).dataBounds.bottom;
- if (pos > numCells) pos = numCells;
-
- dataPos = 12;
- numGroups = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
-
- ClearStatus(wind);
-
- /* Check for duplicate groups, both duplicates within the scrap data
- and duplicates between the scrap data and the target window. Also
- check for groups which no longer exist in the full group list.
-
- For each group in the scrap data, the byte immediately following
- the group name length byte is set to 0 to skip the group, either
- because it is a duplicate within the scrap data or because it no
- longer exists in the full group list. */
-
- numDuplicates = 0;
- numNotInFullGroupList = 0;
- for (i = 0; i < numGroups; i++) {
- groupNameLen = *(unsigned char*)(*data + dataPos);
- dataPos++;
- BlockMoveData(*data + dataPos, groupName, groupNameLen);
- *(groupName + groupNameLen) = 0;
- index = FindGroupIndex(groupName);
- if (index == -1) {
- nameOffset = -1;
- numNotInFullGroupList++;
- } else {
- nameOffset = (*gFullGroupArray)[index].nameOffset;
- for (j = 0, jDataPos = 16; j < i; j++) {
- jGroupNameLen = *(unsigned char*)(*data + jDataPos);
- jDataPos++;
- if (jGroupNameLen == groupNameLen &&
- strncmp(*data + jDataPos, groupName, groupNameLen) == 0)
- {
- nameOffset = -1;
- break;
- }
- jDataPos += jGroupNameLen;
- jDataPos = ((jDataPos + 3) >> 2) << 2;
- jDataPos += 3*sizeof(long);
- numUnreadPairs = *(long*)(*data + jDataPos);
- jDataPos += sizeof(long);
- jDataPos += numUnreadPairs * 2 * sizeof(long);
- }
- if (nameOffset >= 0 && GroupInList(nameOffset, wind)) {
- dupNameOffset = nameOffset;
- numDuplicates++;
- }
- }
- if (nameOffset == -1) *(*data + dataPos) = 0;
- dataPos += groupNameLen;
- dataPos = ((dataPos + 3) >> 2) << 2;
- dataPos += 3*sizeof(long);
- numUnreadPairs = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- dataPos += numUnreadPairs * 2 * sizeof(long);
- }
-
- if (numDuplicates > 0) {
- err = PresentDuplicateGroupsAlert(numDuplicates, dupNameOffset, true);
- if (err != noErr) goto exit;
- }
-
- dataPos = 16;
- firstPos = pos;
- numSubscribed = 0;
- for (i = 0; i < numGroups; i++) {
- groupNameLen = *(unsigned char*)(*data + dataPos);
- dataPos++;
- BlockMoveData(*data + dataPos, groupName, groupNameLen);
- dataPos += groupNameLen;
- dataPos = ((dataPos + 3) >> 2) << 2;
- if (*groupName == 0) {
- dataPos += 3*sizeof(long);
- numUnreadPairs = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- dataPos += numUnreadPairs * 2 * sizeof(long);
- } else {
- *(groupName + groupNameLen) = 0;
- index = FindGroupIndex(groupName);
- nameOffset = (*gFullGroupArray)[index].nameOffset;
- theGroup.nameOffset = nameOffset;
- theGroup.firstMess = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- theGroup.lastMess = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- theGroup.numUnread = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- theGroup.onlyRedrawCount = false;
- numUnreadPairs = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- prevUnread = nil;
- while (numUnreadPairs--) {
- err = MyNewHandle(sizeof(TUnread), &unread);
- if (err != noErr) goto exit;
- (**unread).firstUnread = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- (**unread).lastUnread = *(long*)(*data + dataPos);
- dataPos += sizeof(long);
- (**unread).next = nil;
- if (prevUnread == nil) {
- theGroup.unread = unread;
- } else {
- (**prevUnread).next = unread;
- }
- prevUnread = unread;
- }
- if (theGroup.firstMess >= 0) {
- err = AddNewGroup(nameOffset, wind, pos, &theGroup, false);
- if (err != noErr) goto exit;
- theGroup.unread = nil;
- } else {
- err = AddNewGroup(nameOffset, wind, pos, nil, false);
- if (err != noErr) goto exit;
- theGroup.unread = nil;
- }
- pos++;
- numSubscribed++;
- }
- }
-
- if (numNotInFullGroupList) NoteMessageNumber(kStrSomeGroupsNotInFullGroupList);
-
- if (numSubscribed == 0) goto exit;
-
- SelectOrDeselectAllListItems(theList, false);
- theCell.h = 0;
- for (theCell.v = firstPos; theCell.v < firstPos + numSubscribed; theCell.v++)
- MyLSetSelect(true, theCell, theList);
-
- if (numDuplicates > 0) {
- err = RemoveDuplicates(wind);
- if (err != noErr) goto exit;
- }
-
- MyLScroll(0, theList);
-
- if (gPrefs.reZoomWindows) {
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit;
- } else {
- SetWindowNeedsZooming(wind);
- }
- RedrawGroupCount(wind);
-
- r = (**theList).rView;
- InvalRect(&r);
-
- SetPort(port);
- return noErr;
-
- exit:
-
- SetPort(port);
- DisposeGroupUnreadList(&theGroup);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- CopyOrMoveSelectedGroups
-
- Copy or move selected groups from a group list window to a user group
- list window.
-
- Entry: srcWindow = pointer to source group list window.
- destWindow = pointer to destination user group list window.
- pos = position of new user group list entries in destination
- window (starting row number of new cells).
- Pass 0x7fff to add at end of list.
- copy = true to copy groups, false to move groups.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr CopyOrMoveSelectedGroups (WindowPtr srcWindow, WindowPtr destWindow, short pos,
- Boolean copy)
- {
- Cell srcCell, destCell;
- TWindow **srcInfo, **destInfo;
- TGroup **srcGroupArray, srcGroup;
- ListHandle srcList, destList;
- short index, cellDataLen;
- short numSelected=0, firstPos, numGroups;
- OSErr err = noErr;
- TGroupWindowKind srcKind;
- GrafPtr port;
- short numDuplicates;
- long nameOffset, dupNameOffset;
- Rect r;
-
- GetPort(&port);
- SetPort(destWindow);
-
- srcInfo = (TWindow**)GetWRefCon(srcWindow);
- srcList = (**srcInfo).theList;
- srcGroupArray = (**srcInfo).groupArray;
- srcKind = (**srcInfo).groupKind;
- destInfo = (TWindow**)GetWRefCon(destWindow);
- destList = (**destInfo).theList;
- numGroups = (**destList).dataBounds.bottom;
- if (pos > numGroups) pos = numGroups;
-
- ClearStatus(destWindow);
-
- SetPt(&srcCell,0,0);
- numDuplicates = 0;
- while (LGetSelect(true, &srcCell, srcList)) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, srcCell, srcList);
- nameOffset = (*srcGroupArray)[index].nameOffset;
- if (GroupInList(nameOffset, destWindow)) {
- dupNameOffset = nameOffset;
- numDuplicates++;
- }
- srcCell.v++;
- }
-
- if (numDuplicates > 0) {
- err = PresentDuplicateGroupsAlert(numDuplicates, dupNameOffset, true);
- if (err != noErr) goto exit;
- }
-
- SetPt(&srcCell,0,0);
- firstPos = pos;
- while (LGetSelect(true, &srcCell, srcList)) {
- numSelected++;
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, srcCell, srcList);
- if (srcKind == kUserGroup) {
- srcGroup = (*srcGroupArray)[index];
- err = AddNewGroup(srcGroup.nameOffset, destWindow, pos,
- &srcGroup, copy);
- if (err != noErr) goto exit;
- if (!copy) {
- srcGroup.unread = nil;
- (*srcGroupArray)[index] = srcGroup;
- }
- } else {
- err = AddNewGroup((*srcGroupArray)[index].nameOffset, destWindow, pos,
- nil, false);
- if (err != noErr) goto exit;
- }
- srcCell.v++;
- pos++;
- }
-
- if (numSelected == 0) goto exit;
-
- if (!copy) {
- err = UnsubscribeSelected(srcWindow);
- if (err != noErr) goto exit;
- }
-
- SelectOrDeselectAllListItems(destList, false);
- destCell.h = 0;
- for (destCell.v = firstPos; destCell.v < firstPos + numSelected; destCell.v++)
- MyLSetSelect(true, destCell, destList);
-
- if (numDuplicates > 0) {
- err = RemoveDuplicates(destWindow);
- if (err != noErr) goto exit;
- }
-
- MyLScroll(0, destList);
-
- if (gPrefs.reZoomWindows) {
- err = DoZoom(destWindow, inZoomOut);
- if (err != noErr) goto exit;
- } else {
- SetWindowNeedsZooming(destWindow);
- }
- RedrawGroupCount(destWindow);
-
- r = (**destList).rView;
- InvalRect(&r);
-
- SetPort(port);
- return noErr;
-
- exit:
-
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- AddGroupToUnsubscribedList
-
- Add a group to the unsubscribed list.
-
- Entry: groupName = group name.
- unsubscribed = handle to unsubscribed list.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr AddGroupToUnsubscribedList (char *groupName, Handle unsubscribed)
- {
- long len, unsubscribedLen;
- char *p, *pEnd, *q;
- OSErr err = noErr;
-
- if (unsubscribed == nil) return noErr;
- len = strlen(groupName);
- unsubscribedLen = MyGetHandleSize(unsubscribed);
- p = *unsubscribed;
- pEnd = p + unsubscribedLen;
- while (p < pEnd) {
- q = p;
- while (q < pEnd && *q != CR) q++;
- q++;
- if (MyStrNEqual(p, groupName, len)) break;
- p = q;
- }
- if (p < pEnd) return noErr;
- err = MySetHandleSize(unsubscribed, unsubscribedLen + len + 2);
- if (err != noErr) return err;
- p = *unsubscribed + unsubscribedLen;
- BlockMoveData(groupName, p, len);
- p += len;
- *p++ = '!';
- *p++ = CR;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- UnsubscribeSelected
-
- Unsubscribe selected newsgroups.
-
- Entry: wind = pointer to user group list window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr UnsubscribeSelected (WindowPtr wind)
- {
- WindowPtr child;
- TWindow **info;
- ListHandle theList;
- TGroup **groupArray, groupInfo;
- Cell theCell;
- short numDel = 0;
- GrafPtr port;
- Rect r;
- OSErr err = noErr;
- short cellDataLen, index;
- CStr255 groupName;
-
- GetPort(&port);
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- groupArray = (**info).groupArray;
-
- LSetDrawingMode(false, theList);
- SetPt(&theCell,0,0);
- while (LGetSelect(true, &theCell, theList)) {
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- if ((child = FindChild(wind, theCell)) != nil) {
- err = DoClose(child);
- if (err != noErr) goto exit;
- }
- groupInfo = (*groupArray)[index];
- DisposeGroupUnreadList(&groupInfo);
- (*groupArray)[index] = groupInfo;
- strcpy(groupName, *gGroupNames + groupInfo.nameOffset);
- err = AddGroupToUnsubscribedList(groupName, (**info).unsubscribed);
- if (err != noErr) goto exit;
- LDelRow(1, theCell.v, theList);
- numDel++;
- }
- LSetDrawingMode(true, theList);
- if (numDel > 0) {
- (**info).changed = true;
- MyLScroll(0, theList);
- r = (**theList).rView;
- InvalRect(&r);
- RedrawGroupCount(wind);
- SetWindowNeedsZooming(wind);
- }
- SetPort(port);
- return noErr;
-
- exit:
-
- SetPort(port);
- return err;
- }
-
-